package com.xfd.learn.aspect;

import com.xfd.learn.utils.LogPrintUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;

/**
 *
 * web请求日志增强
 * 小tips :
 *      before 与 around 的执行先后顺序不固定，
 *      有可能around的先开始执行，所以尽量所有日志增强都在around增强进行
 *
 * @since 2024-10-23
 * @author xfd
 */
@Aspect
public class RequestLoggerAspect {

    /**
     * 切点：所有controller层请求
     */
    @Pointcut("(@annotation(org.springframework.web.bind.annotation.RequestMapping) || " +
            "@annotation(org.springframework.web.bind.annotation.GetMapping) || " +
            "@annotation(org.springframework.web.bind.annotation.PostMapping)) && " +
            "(@within(org.springframework.stereotype.Controller) || " +
            "@within(org.springframework.web.bind.annotation.RestController))")
    public void pointCut() {}


    /**
     * 前置增强
     */
    @Before("pointCut()")
    public void before(JoinPoint joinPoint) {
        LogPrintUtil.info("=======================================================> ");
        LogPrintUtil.info("=====> before ");
    }

    /**
     * 环绕增强
     *
     *
     *
     */
    @Around("pointCut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        LogPrintUtil.info("=====> around before ");
//        HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
//        String traceId = request.getHeader(LoggerConstant.REQUEST_TRACE_ID);
//        if (!StringUtils.hasLength(traceId)) {
//            traceId = UUID.randomUUID().toString().replace("-", "");
//        }
//        MDC.put(LoggerConstant.REQUEST_TRACE_ID, traceId);
//        LogPrintUtil.info("============================== request start : trace id [{}]==============================", traceId);
        Object result = joinPoint.proceed();
        LogPrintUtil.info("=====> around after ");
        return result;
    }


    /**
     * 后置增强
     */
    @After(value = "pointCut()")
    public void after() {
        LogPrintUtil.info("=====> after ");
    }

    /**
     * 返回后后置增强
     */
    @AfterReturning(pointcut = "pointCut()", returning = "result")
    public void afterReturning(JoinPoint joinPoint, Object result) {
        LogPrintUtil.info("=====> afterReturning {}", result);
    }

    /**
     * 异常后增强
     */
    @AfterThrowing(pointcut = "pointCut()", throwing = "error")
    public void afterThrowing(JoinPoint joinPoint, Throwable error) {
        LogPrintUtil.info("=====> afterThrowing {}", error);
    }
}
